<template>
  <div>
    <el-table
      :data="tableData"
      @selection-change="handleSelectionChange"
      :span-method="spanMethod"
      ref="tableRef"
      :row-key="(row: any) => row[rowKey]"
      :border="true"
      v-bind="tableProps"
    >
      <el-table-column v-if="selection" type="selection" width="55" :align="'center'" :selectable="(row: any, index: number) => selectableFn(row, index)" />
      <el-table-column v-for="column in props.columns" :key="column.prop" :prop="column.prop" :label="column.label" v-bind="column.props">
        <template v-if="column.slot" #default="scope">
          <slot :name="column.slot" v-bind="scope"></slot>
        </template>
      </el-table-column>
    </el-table>
    <div class="flex justify-end mt-3" v-if="showPagination">
      <el-pagination
        v-model:currentPage="page"
        v-model:page-size="limit"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults';
  import { computed, nextTick, ref } from 'vue';

  interface IColumns {
    prop: string;
    label: string;
    [key: string]: any;
  }
  const props = withDefaults(
    defineProps<{
      columns: Array<IColumns>;
      data: Array<any>;
      selection?: boolean;
      page?: number;
      limit?: number;
      total: number;
      rowKey?: string;
      showPagination?: boolean;
      selectableFn?: (row: any, index: number) => void;
      tableProps?: any;
      spanMethod?: (data: { row: any; rowIndex: number; column: TableColumnCtx<any>; columnIndex: number }) => number[] | { rowspan: number; colspan: number } | undefined;
    }>(),
    {
      data: () => [],
      selection: false,
      page: 1,
      limit: 10,
      total: 0,
      rowKey: 'id',
      showPagination: true,
      selectableFn: () => true,
      spanMethod: () => {
        return {
          rowspan: 1,
          colspan: 1,
        };
      },
    },
  );

  const emit = defineEmits(['change', 'selectionChange']);
  const tableRef = ref();

  const tableData = computed(() => props.data);
  const total = computed(() => props.total);
  const rowKey = computed(() => props.rowKey);
  const selectableFn = computed(() => props.selectableFn);
  const limit = computed(() => props.limit);
  const page = computed(() => props.page);
  const showPagination = computed(() => props.showPagination);
  const spanMethod = computed(() => props.spanMethod);
  const tableProps = computed(() => props.tableProps);

  const handleSizeChange = (val: number) => {
    console.log(`${val} items per page`);
    emit('change', { limit: val, page: 1 });
  };
  const handleCurrentChange = (val: number) => {
    console.log(`current page: ${val}`);
    emit('change', { page: val });
  };

  const multipleSelection = ref<any[]>([]);
  const handleSelectionChange = (val: any[]) => {
    multipleSelection.value = val;
    emit('selectionChange', multipleSelection.value);
  };

  // 设置选中状态
  const setSelection = (datas: any[], flag: any) => {
    nextTick(() => {
      datas.forEach((item) => {
        tableRef.value && tableRef.value.toggleRowSelection(item, flag);
      });
    });
  };

  // 清空选中
  const clearSelection = () => {
    tableRef.value && tableRef.value.clearSelection();
  };

  defineExpose({
    setSelection,
    clearSelection,
  });
</script>
